package sgfRead;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import com.gobaduchi.sgfutils.SGFTreeNode;
import com.gobaduchi.sgfutils.SGFTreeNodeProperty;
import com.gobaduchi.sgfutils.SGFTreeParser;
import com.sun.org.apache.xalan.internal.lib.NodeInfo;

public class SGFReader {
	String sgfFile;
	SGFTreeNode root;
	GameInfos gameInfos;
	int cur = 1;

	public SGFReader(String file) {
		this.sgfFile = file;
	}

	public SGFTreeNode getSGFTreeNode() {
		return root;
	}

	public void doParseFile() {
		SGFTreeParser parser = new SGFTreeParser();
		try {
			root = parser.parse(this.doReaderFile());

			this.parseGameInfos();
			// System.out.println("helloworld \n\n\n");
			String show = root.toString();
			System.out.println(show);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void parseGameInfos() {
		GameInfos ret = new GameInfos();
		SGFTreeNode temp = root.children.get(0);
		for (SGFTreeNodeProperty pro : temp.properties) {
			// AP, CA, FF, GM, ST, SZ
			if (pro.name.compareToIgnoreCase("AP") == 0) {
				ret.ap = pro.value;
			} else if (pro.name.compareToIgnoreCase("CA") == 0) {
				ret.ca = pro.value;
			} else if (pro.name.compareToIgnoreCase("FF") == 0) {
				ret.ff = Integer.parseInt(pro.value);
			} else if (pro.name.compareToIgnoreCase("GM") == 0) {
				ret.gm = Integer.parseInt(pro.value);
			} else if (pro.name.compareToIgnoreCase("ST") == 0) {
				ret.st = Integer.parseInt(pro.value);
			} else if (pro.name.compareToIgnoreCase("SZ") == 0) {
				ret.sz = Integer.parseInt(pro.value);
			} else if (pro.name.compareToIgnoreCase("PW") == 0) {
				ret.pw = pro.value;
			} else if (pro.name.compareToIgnoreCase("PB") == 0) {
				ret.pb = pro.value;
			} else if (pro.name.compareToIgnoreCase("WR") == 0) {
				ret.wr = pro.value;
			} else if (pro.name.compareToIgnoreCase("BR") == 0) {
				ret.br = pro.value;
			}
		}
		this.gameInfos = ret;
	}

	public GameInfos getGameInfos() {
		return this.gameInfos;
	}

	private String doReaderFile(String string) {
		this.sgfFile = string;
		return this.doReaderFile();
	}

	public SgfPosition getNextMove() {
		SGFTreeNode temp = this.root.children.get(cur);
		NodeInfos node = this.parseNodeInfos(temp);
		doIncCur();
		if (!node.b.isEmpty()) {
			SgfPosition pos = new SgfPosition(node.b);
			pos.setBlack();
			return pos;
		} else if (!node.w.isEmpty()) {
			SgfPosition pos = new SgfPosition(node.w);
			pos.setWhite();
			return pos;
		}

		return null;

	}

	public SgfPosition getBackMove() {
		SGFTreeNode temp = this.root.children.get(cur);
		NodeInfos node = this.parseNodeInfos(temp);
		doDecCur();
		if (!node.b.isEmpty()) {
			SgfPosition pos = new SgfPosition(node.b);
			pos.setBlack();
			return pos;
		} else if (!node.w.isEmpty()) {
			SgfPosition pos = new SgfPosition(node.w);
			pos.setWhite();
			return pos;
		}

		return null;
	}

	private void doDecCur() {
		if (cur > (1))
			cur--;

	}

	private void doIncCur() {
		if (cur < (this.root.children.size() - 1))
			cur++;
	}

	private NodeInfos parseNodeInfos(SGFTreeNode temp) {
		NodeInfos ret = new NodeInfos();
		for (SGFTreeNodeProperty pro : temp.properties) {
			if (pro.name.compareToIgnoreCase("c") == 0) {
				ret.c = pro.value;
			} else if (pro.name.compareToIgnoreCase("b") == 0) {
				ret.b = pro.value;
			} else if (pro.name.compareToIgnoreCase("w") == 0) {
				ret.w = pro.value;
			}
		}
		return ret;
	}

	private String doReaderFile() {
		String ret = "";
		try {
			BufferedReader br = new BufferedReader(new FileReader(sgfFile));
			String s;
			while ((s = br.readLine()) != null) {
				ret += s + "\n";
			}
			br.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ret;
	}

	public int getBoardType() {

		return this.gameInfos.sz;
	}

}
